<template>
	<div class="overview">
		<div class="top_bar">
			<p>数据统计</p>
			<div class="data_picker">
				<el-radio-group v-model="day" style="margin-right: 10px">
					<el-radio-button label="今天" @click="changeDay('今天')" />
					<el-radio-button label="昨天" @click="changeDay('昨天')" />
					<el-radio-button label="前天" @click="changeDay('前天')" />
					<el-radio-button label="近一周" @click="changeDay('近一周')" />
				</el-radio-group>
				<!-- <el-date-picker v-model="dateRange" type="daterange" range-separator="到" start-placeholder="开始时间" end-placeholder="结束时间" /> -->
			</div>
		</div>
		<section v-loading="infoLoading" class="data_section">
			<!-- 重要指标 -->
			<div class="view_box">
				<div class="title">
					<p>
						<span class="line"></span>
						<span>重要指标</span>
					</p>
				</div>
				<div class="flex_bar">
					<el-row :gutter="16">
						<el-col v-for="(item, index) of importantList" :key="index" :span="4">
							<div class="flex_item">
								<img :src="item.pic" alt="" />
								<div class="item_right">
									<p>
										{{ item.label }}
										<!-- <span v-if="index == 4">(成功率)</span>
										<span v-if="index == 5">(失败率)</span> -->
										<el-tooltip v-if="index == 3" content="包含等待中，执行中，执行成功和执行失败">
											<img src="@/assets/rzg/info.png" class="tips" alt="" />
										</el-tooltip>
									</p>
									<p>
										{{ item.value }} 
										<!-- <span v-if="index == 4">({{ item.percent }}%)</span><span v-if="index == 5">({{ item.percent }}%)</span> -->
									</p>
									<p v-if="index < 3">系统配置{{ item.label }}</p>
									<p v-if="index == 3">调度中心触发调度次数</p>
									<p v-if="index == 4">调度任务执行成功数量</p>
									<p v-if="index == 5">调度任务执行失败数量</p>
								</div>
							</div>
						</el-col>
					</el-row>
				</div>
			</div>
			<!-- 任务调用情况 -->
			<div class="view_box">
				<div class="title">
					<p>
						<span class="line"></span>
						<span>任务调用情况</span>
					</p>
					<div class="select">
						<el-select v-model="value1" class="m-2" placeholder="请选择调度组" clearable @change="selectSchedulerOne">
							<el-option v-for="item in schedulerList" :key="item.value" :label="item.label" :value="item.value" />
						</el-select>
					</div>
				</div>
				<div class="task_body">
					<div class="task_left">
						<p class="task_title">各时段任务执行分布数</p>
						<div style="display: flex">
							<div style="width: 13%">
								<div class="task_tag">
									<p>执行成功次数</p>
									<p>{{ successTotal }}</p>
									<p>
										占比 <el-tag round>{{ successPercent }}%</el-tag>
									</p>
								</div>
								<div class="task_tag">
									<p>执行失败次数</p>
									<p>{{ failTotal }}</p>
									<p>
										占比 <el-tag round>{{ failPercent }}%</el-tag>
									</p>
								</div>
							</div>
							<div id="task_bar" style="width: 87%; min-height: 300px"></div>
						</div>
					</div>
					<div class="task_right">
						<p class="task_title">任务发布状态</p>
						<div id="task_pie" style="width: 100%; min-height: 300px"></div>
					</div>
				</div>
			</div>
			<!-- 执行耗时排行 -->
			<div class="view_box">
				<div class="title">
					<p>
						<span class="line"></span>
						<span>执行成功耗时排行</span>
					</p>
					<div class="select">
						<el-select v-model="value2" class="m-2" placeholder="请选择调度组" clearable @change="selectSchedulerTwo">
							<el-option v-for="item in schedulerList" :key="item.value" :label="item.label" :value="item.value" />
						</el-select>
					</div>
				</div>
				<div class="rank_body">
					<div class="rank_left">
						<div class="rank_tag">
							<p>
								最大耗时
								<!-- <img src="@/assets/rzg/info.png" alt="" /> -->
							</p>
							<p>{{ rankData ? rankData.max_sec + ' s' : '-' }}</p>
						</div>
						<div class="rank_tag">
							<p>
								最小耗时
								<!-- <img src="@/assets/rzg/info.png" alt="" /> -->
							</p>
							<p>{{ rankData ? rankData.min_sec + ' s' : '-' }}</p>
						</div>
						<div class="rank_tag">
							<p>
								平均耗时
								<!-- <img src="@/assets/rzg/info.png" alt="" /> -->
							</p>
							<p>{{ rankData ? rankData.avg_sec + ' s' : '-' }}</p>
						</div>
					</div>
					<div class="rank_right">
						<el-table :data="dataList" style="width: 100%" height="290" :header-cell-style="{ background: '#f2f3f5' }">
							<el-table-column align="center" prop="rk" label="排名" width="60" />
							<el-table-column align="center" prop="name" label="调度任务名称">
								<template #default="scope">
									<el-text type="primary">{{ scope.row.name }}</el-text>
								</template>
							</el-table-column>
							<el-table-column align="center" prop="groupOwner" label="任务负责人" />
							<el-table-column align="center" prop="startTime" label="任务开始时间" />
							<el-table-column align="center" prop="endTime" label="任务结束时间" />
							<el-table-column align="center" prop="execSec" label="运行时长" />
						</el-table>
					</div>
				</div>
			</div>
			<!-- 执行器情况 -->
			<div class="view_box">
				<div class="title">
					<p>
						<span class="line"></span>
						<span>
							执行器情况
							<el-tooltip content="正常且安装探针的前置机执行器">
								<img src="@/assets/rzg/info.png" class="tips" alt="" />
							</el-tooltip>
						</span>
					</p>
					<div class="select">
						<span
							>执行器：{{ actuatorList.filter(item => item.value == value3)[0]?.label }} 注册地址：{{
								actuatorList.filter(item => item.value == value3)[0]?.ip
							}}&nbsp;&nbsp;&nbsp;</span
						>
						<el-select v-model="value3" class="m-2" placeholder="请选择执行器" @change="selectActuator">
							<el-option v-for="item in actuatorList" :key="item.value" :label="item.label" :value="item.value" />
						</el-select>
					</div>
				</div>
				<div class="flex_bar">
					<el-row :gutter="16">
						<el-col v-for="(item, index) of statusList" :key="index" :span="6">
							<div class="flex_item">
								<img :src="item.pic" alt="" />
								<div class="item_right">
									<p>{{ item.name }}</p>
									<p>{{ item.value }}</p>
								</div>
							</div>
						</el-col>
					</el-row>
				</div>
			</div>
		</section>
	</div>
</template>
<script setup lang="ts">
import { QuestionFilled } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue'
import {
	getStatistics,
	getStatisticsTime,
	getStatisticsRatio,
	getStatisticsStatus,
	getStatisticsChose,
	getStatisticsList,
	getStatisticsExecution
} from '@/api/task-scheduling/index'
import { ScheduleGroupList } from '@/api/auth-hm'
import actuator_item1 from '../../../assets/rzg/actuator_item1.png'
import actuator_item2 from '../../../assets/rzg/actuator_item2.png'
import actuator_item3 from '../../../assets/rzg/actuator_item3.png'
import actuator_item4 from '../../../assets/rzg/actuator_item4.png'
import important_item1 from '../../../assets/rzg/important_item1.png'
import important_item2 from '../../../assets/rzg/important_item2.png'
import important_item3 from '../../../assets/rzg/important_item3.png'
import important_item4 from '../../../assets/rzg/important_item4.png'
import important_item5 from '../../../assets/rzg/important_item5.png'
import important_item6 from '../../../assets/rzg/important_item6.png'
import timeFormater from 'time-formater'

let mainChart = echarts
let infoLoading = ref(true)
const day = ref('今天')
const dateRange = ref([
	timeFormater(new Date(new Date(new Date().toLocaleDateString()).getTime())).format('YYYY-MM-DD HH:mm:ss'),
	timeFormater(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1)).format('YYYY-MM-DD HH:mm:ss')
])
const value1 = ref('')
const value2 = ref('')
const value3 = ref('')

const importantList = ref([])
const statusList = ref([])

const dataList = ref([])
const rankData = ref({})

const schedulerList = ref([])
const actuatorList = ref([])
// 任务调用情况
const pieData = ref([])
const successData = ref([])
const failData = ref([])
const timeList = ref([])
const successTotal = ref(0)
const failTotal = ref(0)
const successPercent = ref(0)
const failPercent = ref(0)

const changeDay = val => {
	document.getElementsByClassName('data_section')[0].scrollTop = 0
	if (val == '今天') {
		dateRange.value = [
			timeFormater(new Date(new Date(new Date().toLocaleDateString()).getTime())).format('YYYY-MM-DD HH:mm:ss'),
			timeFormater(new Date(new Date(new Date().toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1)).format('YYYY-MM-DD HH:mm:ss')
		]
	} else if (val == '昨天') {
		dateRange.value = [
			timeFormater(new Date(new Date(new Date(new Date().getTime() - 24 * 60 * 60 * 1000).toLocaleDateString()).getTime())).format(
				'YYYY-MM-DD HH:mm:ss'
			),
			timeFormater(
				new Date(new Date(new Date(new Date().getTime() - 24 * 60 * 60 * 1000).toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1)
			).format('YYYY-MM-DD HH:mm:ss')
		]
	} else if (val == '前天') {
		dateRange.value = [
			timeFormater(new Date(new Date(new Date(new Date().getTime() - 2 * 24 * 60 * 60 * 1000).toLocaleDateString()).getTime())).format(
				'YYYY-MM-DD HH:mm:ss'
			),
			timeFormater(
				new Date(new Date(new Date(new Date().getTime() - 2 * 24 * 60 * 60 * 1000).toLocaleDateString()).getTime() + 24 * 60 * 60 * 1000 - 1)
			).format('YYYY-MM-DD HH:mm:ss')
		]
	} else {
		dateRange.value = [
			timeFormater(new Date(new Date(new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000).toLocaleDateString()).getTime())).format(
				'YYYY-MM-DD HH:mm:ss'
			),
			timeFormater(new Date(new Date(new Date().toLocaleDateString()).getTime() - 1)).format('YYYY-MM-DD HH:mm:ss')
		]
	}
	getDatas()
	getRankData()
}

const selectActuator = val => {
	getStatisticsStatus(val).then(res => {
		statusList.value = []
		statusList.value.push({
			value: res.data.cpu_usage,
			name: 'CPU使用率',
			pic: actuator_item1
		})
		statusList.value.push({
			value: res.data.mem_usage,
			name: '内存使用率',
			pic: actuator_item2
		})
		statusList.value.push({
			value: res.data.disk_usage,
			name: '磁盘使用率',
			pic: actuator_item3
		})
		statusList.value.push({
			value: res.data.delay,
			name: '延迟',
			pic: actuator_item4
		})
	})
}
const selectSchedulerOne = val => {
	getStatisticsData(val)
}
const selectSchedulerTwo = val => {
	getRankData(val)
}

onMounted(() => {
	init()
	getDatas()
	getRankData()
})

onUnmounted(() => {
	mainChart.dispose
})

const init = () => {
	getStatisticsChose().then((res: any) => {
		actuatorList.value = res.data
		actuatorList.value.forEach(item => {
			item.value = item.id
			item.label = item.appName
		})
		value3.value = actuatorList.value[0].id
		selectActuator(actuatorList.value[0].id)
	})
	ScheduleGroupList({}).then((res: any) => {
		if (res.code == 0) {
			schedulerList.value = res.data
			schedulerList.value.forEach(item => {
				item.value = item.id
				item.label = item.groupName
			})
		}
	})
}

const getDatas = () => {
	infoLoading.value = true
	importantList.value = []

	getStatistics(dateRange.value[0], dateRange.value[1])
		.then((res: any) => {
			infoLoading.value = false
			importantList.value.push({
				label: '调度组数量',
				value: res.data.scheduleGroup,
				pic: important_item1
			})
			importantList.value.push({
				label: '执行器数量',
				value: res.data.execute,
				pic: important_item2
			})
			importantList.value.push({
				label: '任务数量',
				value: res.data.productionSchedule,
				pic: important_item3
			})
			importantList.value.push({
				label: '调度次数',
				value: res.data.totCnt,
				pic: important_item4
			})
			importantList.value.push({
				label: '成功次数',
				value: res.data.successCnt,
				percent: res.data.successRto,
				pic: important_item5
			})
			importantList.value.push({
				label: '失败次数',
				value: res.data.failCnt,
				percent: res.data.failRto,
				pic: important_item6
			})
		})
		.catch(() => {
			infoLoading.value = false
		})
	getStatisticsData()
}

const getStatisticsData = val => {
	getStatisticsTime(dateRange.value[0], dateRange.value[1], val ? val : value1.value).then((res: any) => {
		successData.value = []
		failData.value = []
		timeList.value = []
		successTotal.value = 0
		failTotal.value = 0
		res.data.forEach(item => {
			successTotal.value += item.successCnt
			failTotal.value += item.failCnt
			successData.value.push(item.successCnt)
			failData.value.push(item.failCnt)
			timeList.value.push(Number(item.time) + '点')
			getBarChart()
		})
		if (successTotal.value + failTotal.value > 0) {
			successPercent.value = ((successTotal.value / (successTotal.value + failTotal.value)) * 100).toFixed(2)
			failPercent.value = ((failTotal.value / (successTotal.value + failTotal.value)) * 100).toFixed(2)
		} else {
			successPercent.value = 0
			failPercent.value = 0
		}
	})
	getStatisticsRatio(val ? val : value1.value).then((res: any) => {
		pieData.value = []
		pieData.value.push({
			value: res.data ? res.data.notReleaseRto : 0,
			count: res.data ? res.data.notReleaseCnt : 0,
			name: '未发布'
		})
		pieData.value.push({
			value: res.data ? res.data.releaseRto : 0,
			count: res.data ? res.data.releaseCnt : 0,
			name: '已发布'
		})
		getPieChart()
	})
}

const getRankData = val => {
	getStatisticsList(dateRange.value[0], dateRange.value[1], val ? val : value2.value).then((res: any) => {
		if (res.code == 0) {
			dataList.value = res.data
			dataList.value.forEach(item => {
				// 组件转换时分秒格式默认从8点开始，所以减去8小时
				item.execSec = timeFormater(item.execSec * 1000 - 8 * 3600000).format('HH:mm:ss')
			})
		}
	})
	getStatisticsExecution(dateRange.value[0], dateRange.value[1], val ? val : value2.value).then((res: any) => {
		if (res.code == 0) {
			rankData.value = res.data
		}
	})
}

const getBarChart = () => {
	const dom = document.getElementById('task_bar')
	let myChart = mainChart.init(dom)

	myChart.setOption({
		tooltip: {
			trigger: 'axis',
			axisPointer: {
				type: 'shadow'
			}
		},
		legend: {
			top: 10,
			right: 20
		},
		grid: {
			left: '3%',
			right: '4%',
			bottom: '3%',
			containLabel: true
		},
		xAxis: [
			{
				type: 'category',
				axisLabel: {
					textStyle: {
						color: '#999'
					}
				},
				data: timeList.value
			}
		],
		yAxis: [
			{
				name: '单位：个',
				axisLabel: {
					textStyle: {
						color: '#999'
					}
				},
				minInterval: 1,
				type: 'value'
			}
		],
		series: [
			{
				name: '执行成功',
				type: 'bar',
				stack: 'Ad',
				color: '#778FF7',
				emphasis: {
					focus: 'series'
				},
				data: successData.value
			},
			{
				name: '执行失败',
				type: 'bar',
				stack: 'Ad',
				color: '#DAE1FF',
				emphasis: {
					focus: 'series'
				},
				data: failData.value
			}
		]
	})
}

const getPieChart = () => {
	const dom = document.getElementById('task_pie')
	let myChart = mainChart.init(dom)

	myChart.setOption({
		tooltip: {
			trigger: 'item',
			formatter: function (params) {
				return '数量:' + params.data.count + '\n' + '占比:' + params.data.value + '%'
			}
		},
		legend: {
			bottom: 1,
			left: 'center',
			formatter: function (name) {
				//图例后添加数值
				let data = pieData.value
				let tarValue
				for (let i = 0; i < data.length; i++) {
					if (data[i].name === name) {
						tarValue = data[i].count
					}
				}
				return name + ' ' + tarValue
			}
		},
		color: ['#FDD467', '#5774F4'],
		series: [
			{
				type: 'pie',
				radius: '65%',
				data: pieData.value,
				emphasis: {
					itemStyle: {
						shadowBlur: 10,
						shadowOffsetX: 0,
						shadowColor: 'rgba(0, 0, 0, 0.5)'
					}
				}
			}
		]
	})
}
</script>
<style lang="scss" scoped>
.overview {
	position: relative;
}
.top_bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	width: 100%;
	background: #fff;
	padding: 8px 16px;
	box-sizing: border-box;
	p {
		font-weight: bold;
		font-size: 16px;
	}
	.data_picker {
		display: flex;
		align-items: center;
	}
}
// .data_section::-webkit-scrollbar {
// 	display: none;
// }
.data_section {
	margin-top: 10px;
	margin-bottom: 40px;
	font-size: 16px;
	color: rgb(16, 16, 16);
	// height: calc(100vh - 200px);
	// overflow-y: auto;
	.view_box {
		padding: 24px;
		margin-top: 16px;
		border-radius: 8px;
		background: #fff;
		width: 100%;
		box-sizing: border-box;
		&:first-child {
			margin-top: 6px;
		}
		.title {
			display: flex;
			align-items: center;
			justify-content: space-between;
			margin-bottom: 16px;
			.line {
				display: inline-block;
				margin-right: 8px;
				width: 3px;
				height: 16px;
				background: #165dff;
			}
			p {
				font-size: 18px;
				font-weight: 600;
				color: #1d2129;
			}
			.tips {
				width: 16px;
				height: 16px;
				transform: translateY(3px);
			}
			.select > span {
				font-size: 14px;
				font-weight: 400;
				color: #4e5969;
			}
		}
		.flex_bar .flex_item {
			background: #f7f8fa;
			border-radius: 6px;
			padding: 24px 16px;
			display: flex;
			align-items: center;
			img {
				width: 48px;
				height: 48px;
				margin-right: 24px;
				&.tips {
					width: 16px;
					height: 16px;
					transform: translateY(3px);
				}
			}
			.item_right p {
				color: #4e5969;
				font-size: 14px;
				&:nth-child(2) {
					font-size: 30px;
					color: #1d2129;
					margin-top: 8px;
					font-weight: bold;
					span {
						font-size: 20px;
					}
				}
				&:nth-child(3) {
					font-size: 12px;
					margin-top: 8px;
				}
			}
		}
		.task_body {
			display: flex;
			.task_title {
				padding: 8px 16px;
				text-align: left;
				background: #f7f8fa;
				font-size: 16px;
				font-weight: 600;
				color: #1d2129;
			}
			.task_left {
				margin-right: 32px;
				width: 76%;
				.task_tag {
					width: 160px;
					height: 123px;
					background: #f7f8fa;
					border-radius: 4px;
					margin-top: 16px;
					padding: 12px 24px;
					box-sizing: border-box;
					p {
						font-size: 14px;
						font-weight: 400;
						color: #4e5969;
						margin-bottom: 8px;
						&:nth-child(2) {
							font-size: 30px;
							font-weight: bold;
							color: #1d2129;
							margin-top: 8px;
						}
					}
				}
			}
			.task_right {
				width: 24%;
			}
		}

		.rank_body {
			display: flex;

			.rank_left {
				margin-right: 32px;
				width: 15%;
				.rank_tag {
					// width: 240px;
					width: 100%;
					height: 87px;
					background: #f7f8fa;
					border-radius: 4px;
					margin-bottom: 16px;
					padding: 12px 24px;
					box-sizing: border-box;
					img {
						width: 16px;
						height: 16px;
						transform: translateY(3px);
					}
					&:last-child {
						margin: 0;
					}
					p {
						font-size: 14px;
						font-weight: 400;
						color: #4e5969;
						&:last-child {
							font-size: 30px;
							font-weight: bold;
							color: #1d2129;
							margin-top: 8px;
						}
					}
				}
			}
			.rank_right {
				width: 85%;
			}
		}
	}
}
::v-deep .el-table__row {
	height: 50px;
}
</style>
